﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Yugi.Client.Card;
using System.Threading;
using Yugi.Client.DataModel;
using Yugi_Gui;
using Common;
namespace Yugi.Client.Control
{
    public partial class YTableControl : UserControl, IInvoke
    {
        //------------------------------Change-------------------------------
        void ThayDoiChiSo(int id, int new_value,bool isCong)
        {
            if (isCong)
            {
                this.Data[id].CardControl.SetCong(new_value);
            }
            else
            {
                this.Data[id].CardControl.SetThu(new_value);
            }
        }
        //---------------------------------Request----------------------------
        #region Request
        
        
        void Process_Request(RequestAPI.ReqestItem item)
        {
            if (choice == null) 
                choice = new CardChoice();
            choice.Data = this.Data;
            choice.Count = item.Number;
            choice.SelectionType = item.Card_Type;
            choice.OnChoiceComplete += new EventHandler(choice_OnChoiceComplete_Request);
            choice.OnError += new Action<object, string>(choice_OnError_Request);
            is_show_dialog_request = true;
            switch (item.Type)
            {
                case YMSG.REQUEST_ASK:
                    Linker.ask_message_box.Message = item.AditionData.ToString();
                    Linker.ask_message_box.OnChoice += new Action<object, string>(ask_message_box_OnChoice);
                    Linker.ask_message_box.ShowMsg();
                    choice.OnChoiceComplete -= new EventHandler(choice_OnChoiceComplete_Request);
                    choice.OnError -= new Action<object, string>(choice_OnError_Request);
                    break;
                case Common.YMSG.REQUEST_CHONBAI_DOITHU_BAN:
                    choice.ListCards = this.model.YSupervisorModel.Doi_Thu.YBaiTrenBan;
                    choice.Begin();
                    if (is_show_dialog_request)
                    {
                        string type = item.Card_Type== YType.Monster ? "Quai Vat" : "Spell/Trap";
                        Linker.ShowDialogBox("Chọn Một Quân Bài "+ type +" Trên Bàn Của Đối Thủ");
                    }
                    break;
                case Common.YMSG.REQUEST_CHONBAI_NGUOICHOI_BAN:
                    choice.ListCards = this.model.YSupervisorModel.Nguoi_Choi.YBaiTrenBan;
                    choice.Begin();
                    if (is_show_dialog_request)
                    {
                        string type = item.Card_Type == YType.Monster ? "Quai Vat" : "Spell/Trap";
                        Linker.ShowDialogBox("Chọn Một Quân Bài" + type + " Trên Bàn");
                    }
                    break;
                case YMSG.REQUEST_CHONBAI_TRENBAN:
                    List<CardModel> temp_list = new List<CardModel>();
                    temp_list.AddRange(this.model.YSupervisorModel.Nguoi_Choi.YBaiTrenBan);
                    temp_list.AddRange(this.model.YSupervisorModel.Doi_Thu.YBaiTrenBan);
                    choice.ListCards = temp_list;
                    choice.Begin();
                    if (is_show_dialog_request)
                    {
                        string type = item.Card_Type == YType.Monster ? "Quai Vat" : "Spell/Trap";
                        Linker.ShowDialogBox("Chọn Một Quân Bài" + type + " Trên Bàn");
                    }
                    break;
                case Common.YMSG.RESPONE_CHONBAI_DANHSACH:
                    List<int> temp = item.AditionData as List<int>;
                    Linker.choic_message_box.Clear();
                    CardModel m;
                    //--------------------Init--------------------------
                    foreach (int i in temp)
                    {
                        m = this.model.YSupervisorModel.Find_Card_All(i);
                        if (m == null)
                            MessageBox.Show("RESPONE_CHONBAI_DANHSACH: Khong tim thay id =" + i.ToString());
                        Linker.choic_message_box.Add(m);
                    }
                    Linker.choic_message_box.NumCardChoice = item.Number;
                    //-------------------Result Action-------------------------
                    Action<object> act = obj =>
                    {
                        List<int> res = obj as List<int>;
                        List<object> ans = new List<object>();
                        ans.Add(item.ID);
                        ans.Add(item.Number);
                        foreach (var i in res)
                        {
                            ans.Add(i);
                        }
                        RequestAPI.SendResponse(ans.ToArray());
                        //----------Xoa Delegate
                        choice.OnChoiceComplete -= new EventHandler(choice_OnChoiceComplete_Request);
                        choice.OnError -= new Action<object, string>(choice_OnError_Request);
                    };
                    //------------------Begin-----------------------
                    Linker.choic_message_box.BeginChoice(act);
                    break;
            }
            
        }
        // Complete Ask
        void ask_message_box_OnChoice(object arg1, string arg2)
        {
            int res = 1;
            if(arg2=="YES")
            {
                res = 1;
            }
            else
            {
                res = 0;
            }
            // Send Answer
            RequestAPI.ReqestItem item = RequestAPI.Get();
            List<object> ans = new List<object>();
            ans.Add(item.ID);
            ans.Add(res);
            RequestAPI.SendResponse(ans.ToArray());

            Linker.ask_message_box.OnChoice -= new Action<object, string>(ask_message_box_OnChoice);
        }

        //Complete
        void choice_OnChoiceComplete_Request(object sender, EventArgs e)
        {
            //Init Answer
            RequestAPI.ReqestItem item = RequestAPI.Get();
            if (item == null) return;
            List<object> ans = new List<object>();
            ans.Add(item.ID);
            ans.Add(item.Number);
            foreach (var i in choice.Choices)
            {
                ans.Add(i.ID);
            }

            // Delete Delegate
            choice.OnChoiceComplete -= new EventHandler(choice_OnChoiceComplete_Request);
            choice.OnError -= new Action<object, string>(choice_OnError_Request);

            // Send Answer   
            RequestAPI.SendResponse(ans.ToArray());
            choice = null;
           
        }

        //Error
        void choice_OnError_Request(object arg1, string arg2)
        {
            is_show_dialog_request = false;

            RequestAPI.ReqestItem item = RequestAPI.Get();
            RequestAPI.SendResponse(item.ID, item.Number, -1);

            // Delete Delegate
            choice.OnChoiceComplete -= new EventHandler(choice_OnChoiceComplete_Request);
            choice.OnError -= new Action<object, string>(choice_OnError_Request);
        }
        bool is_show_dialog_request;
        
        #endregion
        //---------------------------------Show Active------------------------
        #region Show_Active
       
        List<object> temp_active_data;
        
        /// <summary>
        /// Show Can Active Message Box
        /// </summary>
        /// <param name="data"></param>
        void ShowActive(object[] data)
        {
            temp_active_data = new List<object>(data);
            Linker.acive_message_box.Clear();
            
            foreach (int item in data)
            {
                Linker.acive_message_box.Add(model.YSupervisorModel.Find_Card_All(item));
                //------------------------La Bai O Tren Ban
                if (Data.ContainsKey(item))
                {
                    Data[item].CardControl.MouseMove += new MouseEventHandler(MouseMove_Active);
                    Data[item].CardControl.MouseLeave += new MouseEventHandler(MouseLeave_Active);
                    Data[item].CardControl.MouseLeftButtonDown += new MouseButtonEventHandler(MouseDown_Active);
                    Linker.MainWindow.control_list_card.lock_click();
                }
                //------------------------La Bai O Trong Mo
                else if (model.YSupervisorModel.Mo_Nguoi_Choi.Containt(item))
                {
                    Tomb list_card = model.YSupervisorModel.Mo_Nguoi_Choi.Presenter as Tomb;
                    HandImage img = list_card.Find(item);
                    img.MouseMove += new MouseEventHandler(Active_img_MouseMove);
                    img.MouseLeave += new MouseEventHandler(Active_img_MouseLeave);
                    img.MouseLeftButtonDown += new MouseButtonEventHandler(Active_img_MouseLeftButtonDown);
                    Linker.MainWindow.control_list_card.lock_click();

                }
                //------------------------La Bai O Tren Tay
                else
                {
                    YCardList list_hand = model.YSupervisorModel.Nguoi_Choi.Presenter as YCardList;
                    HandImage img = list_hand.FindControl(item);
                    img.MouseMove += new MouseEventHandler(Active_img_MouseMove);
                    img.MouseLeave += new MouseEventHandler(Active_img_MouseLeave);
                    img.MouseLeftButtonDown += new MouseButtonEventHandler(Active_img_MouseLeftButtonDown);
                    Linker.MainWindow.control_list_card.lock_click();
                }
                
            }
            Linker.acive_message_box.Message="Có "+data.Length + " lá bài có thể kich hoạt.Bạn vui lòng Click vào lá muốn kích hoạt. Click Esc để chấm dứt";
            Linker.acive_message_box.OnChoice += new Action<object, string>(acive_message_box_OnChoice);
            Linker.acive_message_box.ShowMsg();
            ((Window)(Linker.MainWindow.Parent)).KeyDown += new KeyEventHandler(YTableControl_KeyDown);
        }

        
        /// <summary>
        /// Show Message Box Again
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void YTableControl_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                CloseActive();
                if(temp_active_data.Count!=0)
                    ShowActive(temp_active_data.ToArray());
            }
        }

        /// <summary>
        /// Close Active
        /// </summary>
        public void CloseActive()
        {
            foreach (int item in temp_active_data)
            {
                if (Data.ContainsKey(item))
                {
                    Data[item].CardControl.MouseMove -= new MouseEventHandler(MouseMove_Active);
                    Data[item].CardControl.MouseLeave -= new MouseEventHandler(MouseLeave_Active);
                    Data[item].CardControl.MouseLeftButtonDown -= new MouseButtonEventHandler(MouseDown_Active);

                    Linker.MainWindow.control_list_card.unlock_click();
                }
                else if (model.YSupervisorModel.Mo_Nguoi_Choi.Containt(item))
                {
                    Tomb list_card = model.YSupervisorModel.Mo_Nguoi_Choi.Presenter as Tomb;
                    HandImage img = list_card.Find(item);
                    img.MouseMove -= new MouseEventHandler(Active_img_MouseMove);
                    img.MouseLeave -= new MouseEventHandler(Active_img_MouseLeave);
                    img.MouseLeftButtonDown -= new MouseButtonEventHandler(Active_img_MouseLeftButtonDown);
                    Linker.MainWindow.control_list_card.unlock_click();
                }
                else
                {
                    YCardList list_hand = model.YSupervisorModel.Nguoi_Choi.Presenter as YCardList;
                    HandImage img = list_hand.FindControl(item);
                    img.MouseMove -= new MouseEventHandler(Active_img_MouseMove);
                    img.MouseLeave -= new MouseEventHandler(Active_img_MouseLeave);
                    img.MouseLeftButtonDown -= new MouseButtonEventHandler(Active_img_MouseLeftButtonDown);
                    Linker.MainWindow.control_list_card.unlock_click();
                }
            }
            Linker.acive_message_box.OnChoice -= new Action<object, string>(acive_message_box_OnChoice);
            ((Window)(Linker.MainWindow.Parent)).KeyDown -= new KeyEventHandler(YTableControl_KeyDown);
        }
        /// <summary>
        /// Get The  Player's Answer
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        void acive_message_box_OnChoice(object arg1, string arg2)
        {
            if (arg2 == "No")
            {
                foreach (int item in temp_active_data)
                {
                    if (Data.ContainsKey(item))
                    {
                        Data[item].CardControl.MouseMove -= new MouseEventHandler(MouseMove_Active);
                        Data[item].CardControl.MouseLeave -= new MouseEventHandler(MouseLeave_Active);
                        Linker.MainWindow.control_list_card.unlock_click();
                    }
                    else if (model.YSupervisorModel.Mo_Nguoi_Choi.Containt(item))
                    {
                        Tomb list_card = model.YSupervisorModel.Mo_Nguoi_Choi.Presenter as Tomb;
                        HandImage img = list_card.Find(item);
                        img.MouseMove -= new MouseEventHandler(Active_img_MouseMove);
                        img.MouseLeave -= new MouseEventHandler(Active_img_MouseLeave);
                        Linker.MainWindow.control_list_card.unlock_click();
                    }
                    else
                    {
                        YCardList list_hand = model.YSupervisorModel.Nguoi_Choi.Presenter as YCardList;
                        HandImage img = list_hand.FindControl(item);
                        img.MouseMove -= new MouseEventHandler(Active_img_MouseMove);
                        img.MouseLeave -= new MouseEventHandler(Active_img_MouseLeave);
                        Linker.MainWindow.control_list_card.unlock_click();
                    }
                }
                Linker.acive_message_box.OnChoice -= new Action<object, string>(acive_message_box_OnChoice);
                ((Window)(Linker.MainWindow.Parent)).KeyDown -= new KeyEventHandler(YTableControl_KeyDown);
                //Send to Server
                this.model.YSupervisorModel.SendMessageToServer(Common.YMSG.RESPONE_CANCEL);
            }
        }
        //----------Table Card---------------------------------------//
        #region Card OnTable Process

        void MouseLeave_Active(object sender, MouseEventArgs e)
        {
            YCard card = sender as YCard;
            card.CloseActiveIcon();
        }

        void MouseDown_Active(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount < 2) return;
            YCard card = sender as YCard;
            card.CloseActiveIcon();
            card.MouseMove -= new MouseEventHandler(MouseMove_Active);
            card.MouseLeave -= new MouseEventHandler(MouseLeave_Active);
            card.MouseLeftButtonDown -= new MouseButtonEventHandler(MouseDown_Active);
            Linker.Lager_img.Source = ((CardModel)card.DataContext).YCard.displayImage;
            Linker.ActiveSchedue.Start();
            Action complete = () =>
            {
                switch (((CardModel)card.DataContext).YCard.CardType)
                {
                    case YType.Monster:
                        model.YSupervisorModel.SendMessageToServer(Common.YMSG.CARD_EXCUTE_SUMMON, ((CardModel)card.DataContext).YCard.ID);
                        break;
                    case YType.Spell:
                        model.YSupervisorModel.SendMessageToServer(Common.YMSG.CARD_EXCUTE_SPELL, ((CardModel)card.DataContext).YCard.ID);
                        break;
                    case YType.Trap:
                        model.YSupervisorModel.SendMessageToServer(Common.YMSG.CARD_EXCUTE_TRAP, ((CardModel)card.DataContext).YCard.ID);
                        break;
                }
                CloseActive();
                temp_active_data.Remove(((CardModel)card.DataContext).YCard.ID);
            };
            Linker.ActiveSchedue.SetFinal(complete);
        }

        void MouseMove_Active(object sender, MouseEventArgs e)
        {
            YCard card = sender as YCard;
            card.ShowActiveIcon();
        }
        #endregion
        //----------------Hand Card------------------------------//
        #region Card OnHand Process
        void Active_img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount < 2) return;
            HandImage card = sender as HandImage;
            card.CurrentState = HandImage.State.Default;
            card.MouseMove -= new MouseEventHandler(Active_img_MouseMove);
            card.MouseLeave -= new MouseEventHandler(Active_img_MouseLeave);
            card.MouseLeftButtonDown -= new MouseButtonEventHandler(Active_img_MouseLeftButtonDown);
            Linker.Lager_img.Source = ((CardModel)card.DataContext).YCard.displayImage;
            Linker.ActiveSchedue.Start();
            Action complete = () =>
            {
                switch (((CardModel)card.DataContext).YCard.CardType)
                {
                    case YType.Monster:
                        model.YSupervisorModel.SendMessageToServer(Common.YMSG.CARD_EXCUTE_SUMMON, ((CardModel)card.DataContext).YCard.ID);
                        break;
                    case YType.Spell:
                        model.YSupervisorModel.SendMessageToServer(Common.YMSG.CARD_EXCUTE_SPELL, ((CardModel)card.DataContext).YCard.ID);
                        break;
                    case YType.Trap:
                        model.YSupervisorModel.SendMessageToServer(Common.YMSG.CARD_EXCUTE_TRAP, ((CardModel)card.DataContext).YCard.ID);
                        break;
                }
                CloseActive();
                temp_active_data.Remove(((CardModel)card.DataContext).YCard.ID);
                
            };
            Linker.ActiveSchedue.SetFinal(complete);
        }

        void Active_img_MouseLeave(object sender, MouseEventArgs e)
        {
            HandImage card = sender as HandImage;
            card.CurrentState = HandImage.State.Default;
            card.image_ability.Visibility = Visibility.Hidden;
        }

        void Active_img_MouseMove(object sender, MouseEventArgs e)
        {
            HandImage card = sender as HandImage;
            card.CurrentState = HandImage.State.Select_Active;
            string s = "/Yugi_Gui;component/Image/activate.png";
            card.image_ability.Source = new BitmapImage(new Uri(s, UriKind.Relative));
            card.image_ability.Visibility = Visibility.Visible;
        }
        #endregion
        #endregion
        //----------------------------Reset---------------------------------//
        public void Reset()
        {
            foreach (var id in this.Data.Keys)
            {
                this.container.Children.Remove(Data[id].Host);
            }
            this.Data.Clear();
            
            queue.Clear();
            state.Clear();
            for (int i = 0; i < 10; i++)
                for (int j = 0; j < 10; j++)
                    this.ViTri[i, j] = false;

            model.Reset();

        }
        //----------------------------API------------------------------------//
        private void SpecialSummon(int player_id,YBaseCard card,Zone zone)
        {
            //--------- The Hien Cua Nguoi CHoi
            if(model.YSupervisorModel.Nguoi_Choi.YPlayer.ID== player_id)
            {
                int x,y;
                this.FindNextPosNormal(out x, out y);
                YCard view = new YCard();
                HostItem host = new HostItem(view, Yugi_Gui.Linker.MainWindow.ActualWidth / 2, Yugi_Gui.Linker.MainWindow.ActualHeight);
                view.DataContext = new CardModel(card, model.YSupervisorModel);
                // Set Khong Cho Phep Doi Cong Thu Tren L Bai Moi dc Summon
                ((CardModel)view.DataContext).DaSetViTri = true;
                // Them vo View
                this.container.Children.Add(host.Host);
                this.model.YSupervisorModel.Nguoi_Choi.YBaiTrenBan.Add(((CardModel)view.DataContext));
                Grid.SetRow(host.Host, x);
                Grid.SetColumn(host.Host, y);


                // Gan Bai Vao Database luu tru
                Data[card.ID] = host;

                view.State = YTrangThaiLaBai.Attact_Up;
                view.IsViewDetail = true;

                // Send Special Summon Xong
                model.YSupervisorModel.SendMessageToServer(Common.YMSG.API_SPECIALSUMMON_XONG, player_id, card.Card_TypeID, card.ID, x, y,zone, Common.YMSG.CARD_TRANGTHAI_DUNG_MO);
            }
            
        }
        private void SpecialSummon_DoiThu(int id_player,YBaseCard temp, int x, int y, Zone zone, YMSG state)
        {
            if (!(temp is YMonsterCard))
                return;

            YCard view = new YCard();
            HostItem host = new HostItem(view, Yugi_Gui.Linker.MainWindow.ActualWidth / 2, 0);
            view.DataContext = new CardModel(temp, model.YSupervisorModel);
            // Set Khong Cho Phep Doi Cong Thu Tren L Bai Moi dc Summon
            ((CardModel)view.DataContext).DaSetViTri = true;
            // Them vo View
            this.container.Children.Add(host.Host);

            Grid.SetRow(host.Host, x);
            Grid.SetColumn(host.Host, y);

            //Update Vi tri
            ViTri[x, y] = true;

            // Gan Bai Vao Database luu tru
            Data[temp.ID] = host;


            // Them Bai vao List Bai Doi Thu
            model.YSupervisorModel.Doi_Thu.YBaiTrenBan.Add((CardModel)view.DataContext);


            switch (state)
            {
                case Common.YMSG.CARD_TRANGTHAI_DUNG_MO:
                    view.State = YTrangThaiLaBai.Attact_Up;
                    break;
                case Common.YMSG.CARD_TRANGTHAI_NAM_UP:
                    view.State = YTrangThaiLaBai.Attact_Up;
                    view.State = YTrangThaiLaBai.Defend_Down;
                    break;
            }
        }
        private void ChangeControl(int player_id1, int card_id, int player_id2)
        {
            HostItem host = Data[card_id];
            int x, y;
            x = Grid.GetRow(host.Host);
            y = Grid.GetColumn(host.Host);
            this.ViTri[x, y] = false;
            //--------------The Hien Cua Nguoi Choi
            if (model.YSupervisorModel.Nguoi_Choi.YPlayer.ID == player_id2)
            {
               
                
                FindNextPosNormal(out x,out y);
                Grid.SetRow(host.Host, x);
                Grid.SetColumn(host.Host, y);
                this.ViTri[x, y] = true;
                model.YSupervisorModel.Nguoi_Choi.YBaiTrenBan.Add((CardModel)host.CardControl.DataContext);
                model.YSupervisorModel.Doi_Thu.YBaiTrenBan.Remove((CardModel)host.CardControl.DataContext);
            }
            //----------The Hien Cua Doi Thu
            else
            {
                x = 1;
                y = 5;
                for (int i = y; i >= 1; i--)
                {
                    if (this.ViTri[x, i] == false)
                    {
                        y = i;
                        break;
                    }
                }

                Grid.SetRow(host.Host, x);
                Grid.SetColumn(host.Host, y);
                this.ViTri[x, y] = true;
                model.YSupervisorModel.Nguoi_Choi.YBaiTrenBan.Remove((CardModel)host.CardControl.DataContext);
                model.YSupervisorModel.Doi_Thu.YBaiTrenBan.Add((CardModel)host.CardControl.DataContext);
            }
        }
        private void MoveTohand(int id)
        {
            HostItem host = Data[id];
            int x=Grid.GetRow(host.Host);
            int y=Grid.GetColumn(host.Host);
            host.SetPosition(this.container.ActualWidth / 2, this.container.ActualHeight+200);
            Action<object> temp = (o) =>
            {
                Delay(1000);
                Data.Remove(id);
                ViTri[x, y] = false;
               
                Action del =()=>{
                    model.YSupervisorModel.Nguoi_Choi.YBaiTrenBan.Remove(host.CardControl.DataContext as CardModel);
                    this.container.Children.Remove(host.Host);
                    // Phuc Hoi Quyen Duoc Ra Bai Cho La Moi Tra Ve Tay
                    if (model.YSupervisorModel.Nguoi_Choi.YStateNow == EnumTable.MainPhase1 || model.YSupervisorModel.Nguoi_Choi.YStateNow == EnumTable.MainPhase2)
                    {
                        model.YSupervisorModel.Nguoi_Choi.Presenter.Do(ClientMSG.KetThucMF);
                        model.YSupervisorModel.Nguoi_Choi.Presenter.Do(ClientMSG.ChonBai);
                    }
                };
                this.Dispatcher.Invoke(del);
            };
            ThreadPool.QueueUserWorkItem(new WaitCallback(temp));
        }
        void MoveToHandDoiThu(int id)
        {
            HostItem host = Data[id];
            int x = Grid.GetRow(host.Host);
            int y = Grid.GetColumn(host.Host);
            host.SetPosition(this.container.ActualWidth / 2, - 400);
            Action<object> temp = (o) =>
            {
                Delay(1000);
                Data.Remove(id);
                ViTri[x, y] = false;

                Action del = () =>
                {
                    model.YSupervisorModel.Doi_Thu.YBaiTrenBan.Remove(host.CardControl.DataContext as CardModel);
                    this.container.Children.Remove(host.Host);

                };
                this.Dispatcher.Invoke(del);
            };
            ThreadPool.QueueUserWorkItem(new WaitCallback(temp));
        }
    }
}
